﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace CloudStorageLight.Core
{
    public class BlobContainerConfig
    {
        public string ContainerTypeName {get; set;}

        public string[] Parameters { get; set; }

        public BlobContainerConfig[] Children { get; set; }

        private LogService Log = new LogService(SystemSettings.Instance.BlobStorage);

        public BlobContainer CreateBlobContainer(string defaultContainer, string defaultConnectionString)
        {
            if (ContainerTypeName == typeof(CompositeBlobContainer).FullName)
            {
                var listCont = new List<BlobAdapterBase>();
                foreach(var item in Children)
                {
                    try
                    {
                        listCont.Add((BlobAdapterBase)CreateObject(item.ContainerTypeName, item.Parameters));
                    }
                    catch (Exception e)
                    {
                        Log.EntryLog("", "", "CreateBlobContainer", "", e.ToString());
                    }
                }
                var container = Parameters[0];
                var connectionString = Parameters[1];
                if (string.IsNullOrEmpty(container) && string.IsNullOrEmpty(connectionString))
                {
                    container = defaultContainer;
                    connectionString = defaultConnectionString;
                }
                return new CompositeBlobContainer(container, connectionString, listCont.ToArray());
            }
            else if (ContainerTypeName == typeof(CompositeBlobContainer).FullName)
            {
                var container = Parameters[0];
                var connectionString = Parameters[1];
                if (string.IsNullOrEmpty(container) && string.IsNullOrEmpty(connectionString))
                {
                    container = defaultContainer;
                    connectionString = defaultConnectionString;
                }

                return new AzureBlobContainer(container, connectionString);
            }
            else
            {
                return (BlobContainer)CreateObject(ContainerTypeName, Parameters);
            }
        }

        public object CreateObject(string typename, string[] parameter)
        {
            var type = Type.GetType(typename);
            if (!SystemSettings.Instance.CanUseFileBlobAdapter)
            {
                if (type == typeof(FileBlobAdapter)) new InvalidOperationException("Not allow to use FileBlobAdapter");
            }
            var cnst = type.GetConstructors().FirstOrDefault(x => x.GetParameters().Count() == parameter.Length);

            if (cnst == null) throw new Exception("config error:" + typename + ":" + string.Join(",",parameter));
            var listObj = new List<object>();
            var idx=0;
            foreach (var para in cnst.GetParameters())
            {
                listObj.Add(Convert.ChangeType(parameter[idx++], para.ParameterType));
            }
            return cnst.Invoke(listObj.ToArray());
        }

        public static BlobContainerConfig Load(string file)
        {
            return LoadFromString(File.ReadAllText(file));
        }


        public static BlobContainerConfig LoadFromString(string config)
        {
            using (var st = new StringReader(config))
            {
                var seri = new XmlSerializer(typeof(BlobContainerConfig));
                return  (BlobContainerConfig)seri.Deserialize(st);
            }
        }

        public string ToXml()
        {
            using (var st = new StringWriter())
            {
                var seri = new XmlSerializer(typeof(BlobContainerConfig));
                seri.Serialize(st, this);
                return st.ToString();
            }
        }

    }

}
